/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = frconfig.c                                         */
/*  NOTE      =                                                    */
/*  DATE      = 2014/11/04 by geyh                                 */
/*******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "frmem.h"
#include "frlog.h"
#include "frsutl.h"
#include "frconfig.h"
#include "frcomm.h"

#define APM_BUFF_SIZE    128
#define APM_FILE_END     3
#define APM_LINE_SUCCESS 4

FILE *frconfig_open(const char *p_filename)
{
    FILE *fp = NULL;
    fp = fopen(p_filename,"r");
    return fp;
}

void frconfig_close(FILE *fp)
{
    fclose(fp);
}

/*******************************************************************************
*  FUNC     :  去除字符串的头尾的空格
*  ARGS     :  src          传入字符串的指针
*           :
*  RTN      :  begin        处理后字符串的头指针
*
*  NOTE     :
*******************************************************************************/
FR_STATIC char *__frtrim(char *src)
{
    if(src == NULL)
        return NULL;

    int i = 0;
    char *begin = src;

    while(src[i] != '\0')
    {
        if(src[i] != ' ' && src[i] != '\t')
            break;
        else
            begin++;
       i++;
    }
    for(i = strlen(src)-1; i >= 0;  i--)
    {
        if(src[i] != ' ' && src[i] != '\t' && src[i] !='\n' && src[i] !='\r')
            break;
        else
            src[i] = '\0';
    }
    return begin;
}

/*******************************************************************************
*  FUNC     :  分析每行的数据获取所求key的值
*  ARGS     :  p_in                          (传入配置文件一行的数据)
*           :  p_key                         (要找的key的值)
            ： pp_value                     （所求key的值）
*  RTN      :  APM_FRCONFIG_SUCC             (normal)
               APM_FRCONFIG_NO_FIND          (normal)   该行中没‘=’
*              APM_FRCONFIG_MEM_ERR          (error)
*  NOTE     :  pp_value 必须外部释放内存
*******************************************************************************/
FR_STATIC int __split_eq_string(char *p_in, char *p_key, char **pp_value)
{
    char *p_line_key = NULL;
    char *p_value = NULL;
    char *p = NULL;
    int i_len_tmp = 0;

    if(p_in == NULL || p_key == NULL || *p_key == '\0')
        return APM_FRCONFIG_NO_FIND;

    p = strchr(p_in, '=');

    if (p == NULL)
        return APM_FRCONFIG_NO_FIND;

    //获取该行的key值首地址
    p_line_key = __frtrim(p_in);

    p[0] = '\0';
    p_line_key = __frtrim(p_line_key);
    i_len_tmp = strlen(p_line_key);

    if(i_len_tmp < strlen(p_key))
        i_len_tmp = strlen(p_key);

    p[0] = '=';
    
    //将__frtrim去掉的空格补回
    if(p - p_line_key > strlen(p_line_key))
        memset(p_line_key + strlen(p_line_key),' ',p - p_line_key - strlen(p_line_key));
        
    //判断所读取行的key是否为所需的key并释放p_line_key
    if(strncasecmp(p_line_key,p_key, i_len_tmp) == 0)
    {

        p++;

        //获取value
        p = __frtrim(p);

        if(*p=='\0')
        {
            p_value = (char *) frmemdup("\0",1);
            *pp_value = p_value;
            return APM_FRCONFIG_SUCC;
        }


        p_value = (char *)frmalloc(strlen(p) + 1);
        if(p_value == NULL)
        {
            FRLOG_ERROR_DETAIL("frmalloc failed");
            return APM_FRCONFIG_MEM_ERR;
        }
        snprintf(p_value,strlen(p) + 1,"%s",p);
        __frtrim(p_value);
        *pp_value = p_value;

    	return APM_FRCONFIG_SUCC;
    }
    // 不是所需的key
    return APM_FRCONFIG_NO_FIND;
}

/*******************************************************************************
*  FUNC     :  分析每行的数据获取所求key的值
*  ARGS     :  p_in                          (传入配置文件一行的数据)
*           :  p_key                         (要找的key的值)
            ： p_i_value                     (所求key的值)
*  RTN      :  APM_FRCONFIG_SUCC                   (normal)
               APM_FRCONFIG_NO_FIND          (normal)   该行中没‘=’
*              APM_FRCONFIG_MEM_ERR          (error)
*  NOTE     :  pp_value 必须外部释放内存
*******************************************************************************/
FR_STATIC int __split_eq_int(char *p_in, char *p_key, int *p_i_value)
{
    char *p_line_key = NULL;
    char *p = NULL;
    int i_len_tmp = 0;

    if(p_in == NULL || p_key == NULL || *p_key == '\0')
        return APM_FRCONFIG_NO_FIND;

    p = strchr(p_in, '=');
    if (p == NULL)
        return APM_FRCONFIG_NO_FIND;

    //获取该行的key值首地址
    p_line_key = __frtrim(p_in);

    p[0] = '\0';
    p_line_key = __frtrim(p_line_key);
    i_len_tmp = strlen(p_line_key);

    i_len_tmp = strlen(p_line_key);
    if(i_len_tmp < strlen(p_key))
        i_len_tmp = strlen(p_key);

    p[0] = '=';

    //将__frtrim去掉的空格补回
    if(p - p_line_key > strlen(p_line_key))
        memset(p_line_key + strlen(p_line_key),' ',p - p_line_key - strlen(p_line_key));

    //判断所读取行的key是否为所需的key并释放p_line_key
    if(strncasecmp(p_line_key,p_key,i_len_tmp) == 0)
    {
        p++;

        //获取value
        p = __frtrim(p);

    	if(*p == '\0')
			return APM_FRCONFIG_NO_FIND;

        *p_i_value = atoi(p);
        return APM_FRCONFIG_SUCC;

    }
    // 不是所需的key
	 return APM_FRCONFIG_NO_FIND;
}

/*******************************************************************************
*  FUNC     :  获取配置文件中的一行的数据
*  ARGS     :  fp_in                            (配置文件指针)
*           :  pp_line                          (得到的一行的数据，传出地址 )
*           :  i_getnotes                       (1:读取注释  0：过滤注释)
*  RTN      :  APM_LINE_SUCCESS                 (normal)
*              APM_FRCONFIG_MEM_ERR             (error)
*  NOTE     :  pp_line外部释放内存
*******************************************************************************/
FR_STATIC int __get_arr_line(FILE *fp_in, char **pp_line, int i_getnotes)
{
    char *p_line = NULL;
    char *p_line_tmp = NULL;
    char arr_line_tmp[APM_BUFF_SIZE];
    int i_size = 0;
    int i_index = 0;

    if(fp_in == NULL)
        return APM_FRCONFIG_MEM_ERR;

    memset(arr_line_tmp,'\0',APM_BUFF_SIZE);

    if(fgets(arr_line_tmp,APM_BUFF_SIZE,fp_in) == NULL)
        return APM_FILE_END;

    //是否过滤注释  不能换行
    if(!i_getnotes)
    {
        if(arr_line_tmp[i_index] == '#')
        {
            while(strlen(arr_line_tmp) == (APM_BUFF_SIZE - 1) && arr_line_tmp[APM_BUFF_SIZE - 2] != '\n')
            {
                if(fgets(arr_line_tmp,APM_BUFF_SIZE,fp_in) == NULL)
                    return APM_FRCONFIG_MEM_ERR;
            }

            return  APM_FRCONFIG_NO_FIND;
        }
    }

    while(1)
    {
        //读入到p_line中   当该行数据超过 APM_BUFF_SIZE
        while(strlen(arr_line_tmp) == (APM_BUFF_SIZE - 1) && arr_line_tmp[APM_BUFF_SIZE - 2] != '\n')
        {
            if(p_line == NULL)
            {
                p_line = (char *)frmalloc(APM_BUFF_SIZE);
                if(p_line == NULL)
                {
                    FRLOG_ERROR_DETAIL("frmalloc failed");
                    return APM_FRCONFIG_MEM_ERR;
                }
                snprintf(p_line,APM_BUFF_SIZE,"%s",arr_line_tmp);
            }
            else
            {
                i_size = strlen(p_line) + APM_BUFF_SIZE;
                p_line_tmp = (char *)frmalloc(i_size);
                if(p_line_tmp == NULL)
                {
                    FRLOG_ERROR_DETAIL("frmalloc failed");
                    frfree(p_line);
                    return APM_FRCONFIG_MEM_ERR;
                }
                snprintf(p_line_tmp,i_size,"%s%s",p_line, arr_line_tmp);
                frfree(p_line);
                p_line = p_line_tmp;
            }
            memset(arr_line_tmp,'\0',APM_BUFF_SIZE);
            if(fgets(arr_line_tmp,APM_BUFF_SIZE,fp_in) == NULL)
            {
                if(feof(fp_in))
                {
                    *pp_line = p_line;
                     return APM_LINE_SUCCESS;
                }
                frfree(p_line);
                return APM_FRCONFIG_MEM_ERR;
            }
        }

        if( p_line != NULL)
        {
            __frtrim(p_line);
            i_size = strlen(p_line) + 1 + strlen(arr_line_tmp);
            p_line_tmp = (char *)frmalloc(i_size);
            if(p_line_tmp == NULL)
            {
                FRLOG_ERROR_DETAIL("frmalloc failed");
                frfree(p_line);
                return APM_FRCONFIG_MEM_ERR;
            }
            snprintf(p_line_tmp,i_size,"%s%s",p_line, arr_line_tmp);
            frfree(p_line);
            p_line = p_line_tmp;
            //判断是否为注释
            p_line_tmp = __frtrim(p_line);
            if(!i_getnotes)
            {
                if(*p_line_tmp == '#')
                    break;
            }
        }
        //数据小于 APM_BUFF_SIZE
        else
        {
            i_size =1 + strlen(arr_line_tmp);
            p_line = (char *)frmalloc(i_size);
            if(p_line == NULL)
            {
                FRLOG_ERROR_DETAIL("frmalloc failed");
                return APM_FRCONFIG_MEM_ERR;
            }
            snprintf(p_line,i_size,"%s",arr_line_tmp);
            memset(arr_line_tmp,'\0',APM_BUFF_SIZE);
            p_line_tmp = __frtrim(p_line);
            if(!i_getnotes)
            {
                if(*p_line_tmp == '#')
                    break;
            }
        }

        //获取下一行数据  看是否是空格开头
        if(fgets(arr_line_tmp,APM_BUFF_SIZE,fp_in) == NULL)
            break;

        //不是tab开头  则将文件指针回移  跳出循环
        if(arr_line_tmp[i_index] != '\t')
        {
            fseek(fp_in,-strlen(arr_line_tmp),1);
            break;
        }
        //如果以tab开头  则将tab以后的数据添加到上一行数据之后
        //并且下一行的数据超过APM_BUFF_SIZE
        if(strlen(arr_line_tmp) == (APM_BUFF_SIZE - 1) && arr_line_tmp[APM_BUFF_SIZE - 2] != '\n')
        {
            p_line_tmp = frstrdup(arr_line_tmp);
            frltrim(p_line_tmp);
            memset(arr_line_tmp,' ',APM_BUFF_SIZE - 1);
            memcpy(arr_line_tmp,p_line_tmp,strlen(p_line_tmp));
            frfree(p_line_tmp);
        }
        //下一行数据少于APM_BUFF_SIZE
        else
        {
            p_line_tmp = frstrdup(arr_line_tmp);
            frltrim(p_line_tmp);
            memset(arr_line_tmp,'\0',APM_BUFF_SIZE);
            memcpy(arr_line_tmp,p_line_tmp,strlen(p_line_tmp));
            frfree(p_line_tmp);
        }
    }


    *pp_line = p_line;
    return APM_LINE_SUCCESS;
}

int frconfig_string(FILE* fp, char *p_key, char **pp_value)
{
    char *p_value = NULL;
    char *p_line = NULL;
    char *p_line_tmp = NULL;
    int i_ret = 0;

    if(fp == NULL)
        return APM_FRCONFIG_MEM_ERR;
    rewind(fp);

    if(p_key == NULL || p_key == '\0')
    	return APM_FRCONFIG_NO_FIND;

    i_ret = __get_arr_line(fp,&p_line,0);
    if(i_ret == APM_FRCONFIG_MEM_ERR)
        return APM_FRCONFIG_MEM_ERR;

    p_line_tmp = p_line;
    p_line_tmp = __frtrim(p_line_tmp);
   
    while(i_ret != APM_FILE_END && i_ret != APM_FRCONFIG_MEM_ERR)
    {
        //读到注释  原数据'#'开头
        if(p_line_tmp == NULL)
        {
            i_ret = __get_arr_line(fp,&p_line,0);
            p_line_tmp = p_line;
            p_line_tmp = __frtrim(p_line_tmp);
            continue;
        }
        //读到空行
        if(*p_line_tmp == '\0')
        {
        	frfree(p_line);
        	p_line = NULL;
        	i_ret = __get_arr_line(fp,&p_line,0);
            p_line_tmp = p_line;
            p_line_tmp = __frtrim(p_line_tmp);
            continue;
        }
        //跳过注释
        if (*p_line_tmp == '#')
        {
        	frfree(p_line);
        	p_line = NULL;
            i_ret = __get_arr_line(fp,&p_line,0);
            p_line_tmp = p_line;
            p_line_tmp = __frtrim(p_line_tmp);
            continue;
        }
        if(__split_eq_string(p_line_tmp,p_key,&p_value) == APM_FRCONFIG_SUCC)
        {
            *pp_value = p_value;
            frfree(p_line);
            p_line = NULL;
            return APM_FRCONFIG_SUCC;
        }
        else
        {
            frfree(p_line);
            p_line = NULL;
            i_ret = __get_arr_line(fp,&p_line,0);
            p_line_tmp = p_line;
            p_line_tmp = __frtrim(p_line_tmp);
            continue;
        }
    }
    if(i_ret == APM_FRCONFIG_MEM_ERR)
        return APM_FRCONFIG_MEM_ERR;

    return APM_FRCONFIG_NO_FIND;
}

int frconfig_int(FILE* fp, char *p_key, int *p_i_value)
{
    int i_value;
    char *p_line = NULL;
    char *p_line_tmp = NULL;
    int i_ret = 0;

    if(fp == NULL)
            return APM_FRCONFIG_MEM_ERR;
    rewind(fp);

    if(p_key == NULL || p_key == '\0')
    	return APM_FRCONFIG_NO_FIND;

    i_ret = __get_arr_line(fp,&p_line,0);
    if(i_ret == APM_FRCONFIG_MEM_ERR)
        return APM_FRCONFIG_MEM_ERR;


    p_line_tmp = p_line;
    p_line_tmp = __frtrim(p_line_tmp);
    while(i_ret != APM_FILE_END && i_ret != APM_FRCONFIG_MEM_ERR)
    {
        //读到注释
        if(p_line_tmp == NULL)
        {
            i_ret = __get_arr_line(fp,&p_line,0);
            p_line_tmp = p_line;
            p_line_tmp = __frtrim(p_line_tmp);
            continue;
        }
        //读到空行
        if(*p_line_tmp == '\0')
        {
        	frfree(p_line);
        	p_line = NULL;
        	i_ret = __get_arr_line(fp,&p_line,0);
            p_line_tmp = p_line;
            p_line_tmp = __frtrim(p_line_tmp);
            continue;
        }
        //读到注释     原数据'#'前有空格
        if (*p_line_tmp == '#')
        {
        	frfree(p_line);
        	p_line = NULL;
            i_ret = __get_arr_line(fp,&p_line,0);
            p_line_tmp = p_line;
            p_line_tmp = __frtrim(p_line_tmp);
            continue;
        }
        if(__split_eq_int(p_line_tmp,p_key,&i_value) == APM_FRCONFIG_SUCC)
        {
            *p_i_value = i_value;
            frfree(p_line);
            p_line = NULL;
            return APM_FRCONFIG_SUCC;
        }
        else
        {
            frfree(p_line);
            p_line = NULL;
            i_ret = __get_arr_line(fp,&p_line,0);
            p_line_tmp = p_line;
            p_line_tmp = __frtrim(p_line_tmp);
            continue;
        }
    }

    if(i_ret == APM_FRCONFIG_MEM_ERR)
        return APM_FRCONFIG_MEM_ERR;

    return APM_FRCONFIG_NO_FIND;
}

int frconfig_get_string(char *p_config_name, char *p_key, char **pp_value)
{
	FILE *fp;
	char *p_value = NULL;
	int i_ret = 0;

	fp = frconfig_open(p_config_name);
	if (fp == NULL)
	{
	    FRLOG_ERROR_DETAIL("open [%s] failed", p_config_name);
	    return APM_FRCONFIG_NO_FIND;
	}

    i_ret = frconfig_string(fp,p_key,&p_value);
	if (i_ret != APM_FRCONFIG_SUCC)
	{
	    frconfig_close(fp);
	    return i_ret;
	}
	*pp_value = p_value;

	frconfig_close(fp);
	return APM_FRCONFIG_SUCC;
}

int frconfig_get_int(char *p_config_name, char *p_key, int *p_i_value)
{
	FILE *fp;
	int i_value = 0;
	int i_ret = 0;

	fp = frconfig_open(p_config_name);
	if (fp == NULL)
	{
	    FRLOG_ERROR_DETAIL("open [%s] failed", p_config_name);
        return APM_FRCONFIG_NO_FIND;
    }

    i_ret = frconfig_int(fp,p_key,&i_value);
	if(i_ret != APM_FRCONFIG_SUCC)
	{
        frconfig_close(fp);
        return i_ret;
    }
	*p_i_value = i_value;

	frconfig_close(fp);
	return APM_FRCONFIG_SUCC;
}

int frconfig_set_string(char *p_config_name, char *p_key, char *p_value)
{
    FILE *fp_config = NULL;
    char *p_config = NULL;
    char *p_line = NULL;
    char arr_line_tmp[APM_BUFF_SIZE];
    char *p_tmp = NULL;
    int i_ret = 0;
    int i_flag = 0;
    int i_size = 0;
    int i_used = 0;
    int i_size_all = 0;
    int i_enter = 0;

    if(p_config_name == NULL || p_key == NULL || p_value == NULL)
    {
        FRLOG_ERROR_DETAIL("config set string failed, config_name=[%s], key=[%s], value=[%s]", p_config_name, p_key, p_value);
        return FR_FAIL;
    }

    fp_config = fopen(p_config_name,"r");
    if(fp_config == NULL)
    {
        FRLOG_ERROR_DETAIL("open [%s] failed", p_config_name);
        return FR_FAIL;
    }

    memset(arr_line_tmp,'\0',APM_BUFF_SIZE);

    p_config = (char *) frmalloc(1024);
    i_size_all += 1024;

    if(p_config == NULL)
    {
        FRLOG_ERROR_DETAIL("frmalloc failed");
        fclose(fp_config);
        return FR_FAIL;
    }

    while(__get_arr_line(fp_config, &p_line,1) != APM_FILE_END)
    {
        i_ret = __split_eq_string(p_line,p_key,&p_tmp);
        __frtrim(p_line);
        //当这行的key为要修改的key时
        if(i_ret == APM_FRCONFIG_SUCC)
        {
            i_flag = 1;
            frfree(p_tmp);
            frfree(p_line);
            p_line = NULL;

            i_size = strlen(p_key) + strlen(p_value) + strlen(" = ") + 2;
            //p_config内存足够时
            if(i_used + i_size < i_size_all)
            {
                snprintf(p_config + i_used,i_size + 1,"%s = %s\r\n",p_key,p_value);
                i_used += i_size;
            }
            //内存不足
            else
            {
                //p_config内存增加足够的内存空间
                i_size_all += ((i_size/1024) + 1) * 1024;
                p_tmp = (char *) frmalloc(i_size_all);
                if(p_tmp == NULL)
                {
                    FRLOG_ERROR_DETAIL("frmalloc failed");
                    frfree(p_config);
                    frfree(p_line);
                    return APM_FRCONFIG_MEM_ERR;
                }
                //p_config继续添加
                snprintf(p_tmp,strlen(p_config) + i_size + 1,"%s%s = %s\r\n",p_config, p_key, p_value);
                i_used += i_size;

                frfree(p_config);
                frfree(p_line);
                p_line = NULL;
                p_config = p_tmp;
            }
        }
        //当前读取行的数据key不是要求修改的内容
        else
        {
            i_size =strlen(p_line) + 2;
            //p_config内存足够
            if(i_used + i_size < i_size_all)
            {
                snprintf(p_config + i_used,i_size + 1,"%s\r\n",p_line);
                frfree(p_line);
                p_line = NULL;
                i_used += i_size;
            }
            //内存不足
            else
            {
                //增加1024
                i_size_all += ((i_size/1024) + 1) * 1024;
                p_tmp = (char *)frmalloc(i_size_all);
                if(p_tmp == NULL)
                {
                    FRLOG_ERROR_DETAIL("frmalloc failed");
                    frfree(p_config);
                    frfree(p_line);
                    p_line = NULL;
                    fclose(fp_config);
                    return APM_FRCONFIG_MEM_ERR;
                }
                //p_config继续添加
                snprintf(p_tmp,strlen(p_config) + i_size + 1,"%s%s\r\n",p_config, p_line);
                frfree(p_config);
                frfree(p_line);
                p_line = NULL;
                p_config = p_tmp;
                i_used += i_size;
            }
        }

        memset(arr_line_tmp,'\0',APM_BUFF_SIZE);

    }

    fclose(fp_config);

    //如果配置文件中不存在key   直接追加在文件末尾
    if(i_flag == 0)
    {
        frfree(p_config);
        fp_config = fopen(p_config_name,"a+");

        if(fp_config == NULL)
        {
            FRLOG_ERROR_DETAIL("open [%s] failed", p_config_name);
            frfree(p_config);
            return FR_FAIL;
        }
        //判断文件是否是换行符结尾
        fseek(fp_config,-1L,SEEK_END);
        if(getc(fp_config)=='\n')
            i_enter = 1;
        rewind(fp_config);

        if(i_enter == 1)
            fprintf(fp_config,"%s = %s\r\n",p_key,p_value);
        else
            fprintf(fp_config,"\r\n%s = %s\r\n",p_key,p_value);

        fclose(fp_config);
        return FR_SUCC;
    }

    //如果文件中存在key  则修改文件数据
    fp_config = fopen(p_config_name,"w");
    if(fp_config == NULL)
    {
        FRLOG_ERROR_DETAIL("open [%s] failed", p_config_name);
        frfree(p_config);
        return FR_FAIL;
    }

    fprintf(fp_config,"%s",p_config);
    fclose(fp_config);
    frfree(p_config);

    return FR_SUCC;
}

int frconfig_set_int(char *p_config_name, char *p_key, int i_value)
{
    char *p_value = NULL;
    int i_ret = 0;

    p_value = (char *)frmalloc(50);
    snprintf(p_value,50,"%d",i_value);

    i_ret = frconfig_set_string(p_config_name,p_key,p_value);
    frfree(p_value);
    return i_ret;

}

int frconfig_del_string(char *p_config_name, char *p_key, char *p_value)
{
    FILE *fp_config = NULL;
    char *p_config = NULL;
    char *p_line = NULL;
    char arr_line_tmp[APM_BUFF_SIZE];
    char *p_tmp = NULL;
    char *p_tmp_value = NULL;
    int i_ret = 0;
    int i_flag = 0;
    int i_size = 0;
    int i_used = 0;
    int i_size_all = 0;

    if(p_config_name == NULL || p_key == NULL || p_value == NULL)
    {
        FRLOG_ERROR_DETAIL("config set string failed, config_name=[%s], key=[%s], value=[%s]", p_config_name, p_key, p_value);
        return FR_FAIL;
    }

    fp_config = fopen(p_config_name,"r");
    if(fp_config == NULL)
    {
        FRLOG_ERROR_DETAIL("open [%s] failed", p_config_name);
        return FR_FAIL;
    }

    memset(arr_line_tmp,'\0',APM_BUFF_SIZE);

    p_config = (char *)frmalloc(1024);
    i_size_all += 1024;

    if(p_config == NULL)
    {
        FRLOG_ERROR_DETAIL("frmalloc failed");
        fclose(fp_config);
        return FR_FAIL;
    }

    //循环读文件
    while(__get_arr_line(fp_config, &p_line,1) != APM_FILE_END)
    {
        __split_eq_string(p_line,p_key,&p_tmp_value);
        __frtrim(p_line);
        if(p_tmp_value != NULL)
        {
        
            if(strcmp(p_tmp_value,p_value) == 0)
            {
                frfree(p_tmp_value);
                p_tmp_value = NULL;
                frfree(p_line);
                p_line = NULL;
                i_ret = APM_FRCONFIG_SUCC;
             }
            else
            {
                frfree(p_tmp_value);
                p_tmp_value = NULL;
                i_ret = APM_FRCONFIG_NO_FIND;
            }
        }
        else
        {
            i_ret = APM_FRCONFIG_NO_FIND;
        }
        //当这行的key为要修改的key时
        if(i_ret == APM_FRCONFIG_SUCC)
        {
            i_flag = 1;
            i_ret = APM_FRCONFIG_NO_FIND;
            continue;
        }
        //当前读取行的数据key不是要求修改的内容
        else
        {
            i_size =strlen(p_line) + 2;
            //p_config内存足够
            if(i_used + i_size < i_size_all)
            {
                snprintf(p_config + i_used,i_size + 1,"%s\r\n",p_line);
                frfree(p_line);
                p_line = NULL;
                i_used += i_size;
            }
            //内存不足
            else
            {
                //增加1024
                i_size_all += 1024;
                p_tmp = (char *) frmalloc(i_size_all);
                if(p_tmp == NULL)
                {
                    FRLOG_ERROR_DETAIL("frmalloc failed");
                    frfree(p_config);
                    frfree(p_line);
                    p_line = NULL;
                    fclose(fp_config);
                    return APM_FRCONFIG_MEM_ERR;
                }
                //p_config继续添加
                snprintf(p_tmp,strlen(p_config) + i_size + 1,"%s%s\r\n",p_config, p_line);
                frfree(p_config);
                frfree(p_line);
                p_line = NULL;
                p_config = p_tmp;
                i_used += i_size;
            }
        }

        memset(arr_line_tmp,'\0',APM_BUFF_SIZE);

    }

    fclose(fp_config);

    //如果配置文件中不存在key 直接释放内存
    if(i_flag == 0)
    {
        frfree(p_config);
        return FR_FAIL;
    }

    //如果文件中存在key  则修改文件数据
    fp_config = fopen(p_config_name,"w");
    if(fp_config == NULL)
    {
        FRLOG_ERROR_DETAIL("open [%s] failed", p_config_name);
        frfree(p_config);
        return FR_FAIL;
    }

    fprintf(fp_config,"%s",p_config);
    fclose(fp_config);
    frfree(p_config);

    return FR_SUCC;
}
